package com.CampusForum.community.controller;

import com.CampusForum.community.annotation.LoginRequired;
import com.CampusForum.community.entity.User;
import com.CampusForum.community.service.UserService;
import com.CampusForum.community.util.CommunityUtil;
import com.CampusForum.community.util.HostHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

@Controller
@RequestMapping("/user")
@Slf4j
public class UserController {
    @Autowired
    private HostHolder hostHolder;
    @Autowired
    private UserService userService;
    @Value("${community.domain}")
    private String domain;
    @Value("${server.servlet.context-path}")
    private String contextPath;
    @Value("${community.avatar}")
    private String avatar;

    /**
     * 返回账号设置页面
     */
    @LoginRequired
    @GetMapping("/setting")
    public String getAccountSettings() {
        return "/site/setting";
    }

    /**
     * 上传头像
     */
    @LoginRequired
    @PostMapping("/upload")
    public String uploadAvatar(MultipartFile headerImage, Model model) {
        if(headerImage == null) {
            model.addAttribute("error", "上传空文件, 上传错误, 请重新上传");
            // 返回账号设置页面重新上传
            return "/site/setting";
        }
        String imageFileName = headerImage.getOriginalFilename();
        if (imageFileName == null) {
            model.addAttribute("error", "文件名为空, 上传错误, 请重新上传");
            // 返回账号设置页面重新上传
            return "/site/setting";
        }
        // 文件后缀
        String suffix = imageFileName.substring(imageFileName.lastIndexOf("."));
        if (StringUtils.isBlank(suffix)) {
            model.addAttribute("error", "文件类型不正确, 上传错误, 请重新上传");
            // 返回账号设置页面重新上传
            return "/site/setting";
        }
        String randomName = CommunityUtil.generateUUID();
        imageFileName = randomName + suffix;

        String headerUrl = domain + contextPath + "/user/header/" + imageFileName;
        // 修改用户头像
        // 获取用户
        User user = hostHolder.getUser();
        userService.updateUserAvatar(user, headerUrl);
        // 把头像上传到服务器本地
        try {
            headerImage.transferTo(new File(avatar + "/" + imageFileName));
        } catch (IOException e) {
            log.error("文件上传服务器本地发送错误 " + e);
        }
        return "redirect:/index";
    }

    /**
     * 从服务器获取头像, 通过response返回给前端
     */
    @GetMapping("/header/{imageFileName}")
    public void getAvatar(@PathVariable("imageFileName") String imageFileName, HttpServletResponse response) {
        if (imageFileName == null) {
            log.info("获取空文件");
            return;
        }
        // 设置response返回的文件类型
        String suffix = imageFileName.substring(imageFileName.lastIndexOf("."));
        response.setContentType("image/"+suffix);
        // 服务器头像地址
        String local = avatar + "/" + imageFileName;

        try(
                FileInputStream fileInputStream = new FileInputStream(local);
                ServletOutputStream outputStream = response.getOutputStream()
        ){
            byte[] walker = new byte[1024];
            int i = 0;
            while ((i = fileInputStream.read(walker)) != -1) {
                outputStream.write(walker);
            }
        } catch (FileNotFoundException e) {
            log.error(e.getMessage());
        } catch (IOException e) {
            log.error(e.getMessage());
        }

    }

    @LoginRequired
    @PostMapping("/update")
    public String updatePassword(@RequestParam("oldPassword") String oldPassword,
                               @RequestParam("newPassword") String newPassword,
                               Model model) {
        Map<String, Object> map = userService.updatePassword(oldPassword, newPassword);
        if (map.get("oldError") != null) {
            model.addAttribute("oldError", map.get("oldError"));
            return "/site/setting";
        }
        if (map.get("newError") != null) {
            model.addAttribute("newError", map.get("newError"));
            return "/site/setting";
        }
        return "redirect:/login";
    }
}
